package cn.com.zhuoyan.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import cn.com.zhuoyan.dao.BaseDao;
import cn.com.zhuoyan.util.Page;

@Repository
@SuppressWarnings({"unchecked","rawtypes"})
public class BaseDaoImpl<T, ID extends Serializable> implements BaseDao<T, Serializable>{
	@Autowired
	private SessionFactory sessionFactory;
	
	private Session getSession(){
        return sessionFactory.getCurrentSession();
    }

	@Override
	public Integer save(Object entity) throws Exception {
		return (Integer) getSession().save(entity);
	}

	@Override
	public List<T> findByHql(String hql, Object... values) throws Exception {
		Query query=getSession().createQuery(hql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				query.setParameter(i, values[i]);
			}
		}
		return query.list();
	}

	@Override
	public T findHqlUnique(String hql, Object... values) throws Exception {
		Query query=getSession().createQuery(hql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				query.setParameter(i, values[i]);
			}
		}
		return (T) query.setMaxResults(1).uniqueResult();
	}

	@Override
	public List<T> findBySql(String sql, Object... values) throws Exception {
		SQLQuery sqlQuery=getSession().createSQLQuery(sql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				sqlQuery.setParameter(i, values[i]);
			}
		}
		return sqlQuery.list();
	}


	@Override
	public T findSqlUnique(String sql, Object... values) throws Exception {
		SQLQuery sqlQuery=getSession().createSQLQuery(sql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				sqlQuery.setParameter(i, values[i]);
			}
		}
		return (T) sqlQuery.setMaxResults(1).uniqueResult();
	}
	
	@Override
	public void updateEntity(Object entity) throws Exception {
		getSession().update(entity);
	}

	@Override
	public int updateHql(String hql,Object... values) throws Exception {
		Query query=getSession().createQuery(hql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				query.setParameter(i, values[i]);
			}
		}
		return query.executeUpdate();
	}

	@Override
	public void removeEntity(Object entity) throws Exception {
		getSession().delete(entity);
	}

	@Override
	public T getById(Class clazz, int id) throws Exception {
		T obj=(T) getSession().get(clazz, id);
		return obj;
	}

	@Override
	public T loadById(Class clazz, int id) throws Exception {
		T obj=(T) getSession().load(clazz, id);
		return obj;
	}

	@Override
	public List<T> getList(Class clazz) throws Exception {
		Criteria cri=getSession().createCriteria(clazz);
		return cri.list();
	}

	@Override
	public Page<T> showPage(String queryHql, int firstResult, int maxResult,Object... values) throws Exception {
		Page<T> page=new Page<T>();
		Query query=getSession().createQuery(queryHql);
		if(values != null){
			for(int i=0;i<values.length;i++){
				query.setParameter(i, values[i]);
			}
		}
		page.setPageSize(maxResult);
		page.setTotalCount(query.list().size());
		page.setCunrrentPage(firstResult);
		List<T> list=query.setFirstResult((page.getCunrrentPage()-1) * page.getPageSize()).setMaxResults(page.getPageSize()).list();
		if(list == null){
			list=new ArrayList<T>();
		}
		page.setList(list);
		return page;
	}
	
}
